//非阻塞等待的间隙, 完成其他任务

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
#include "func.h"
#include <sys/types.h>

typedef void (*func_t)();
#define N 3
func_t tasks[N] = {NULL};

void LoadTask()//加载任务
{
    tasks[0] = PrintLog;//函数名就是地址
    tasks[1] = DownLoad;
    tasks[2] = MysqlDataSync;
}

void HandlerTask()//处理任务
{
    LoadTask();
    for (int i=0; i<N; i++)
    {
        tasks[i]();
        //PrintLog();
    }
}

void DoOtherThing()//父进程阻塞时, 做其他事
{
    HandlerTask();
}

void ChildRun()
{
    //int* p = NULL;
    //*p = 100;
    int cnt = 5;//count
    while (cnt--)
    {
        printf("I am child process, pid:%d, ppid:%d, cnt:%d\n", getpid(), getppid(), cnt);
        sleep(1);
    }
}

int main()
{
    pid_t id = fork();
    if (0 == id)
    {
        //child
        ChildRun();
        printf("child quit...\n");
        exit(0);
    }
    else //id是子进程的pid
    {
        //parent
        //sleep(7);//为了看到子进程的Z状态
        while (1)
        {
            //非阻塞等待 + 循环 == 非阻塞轮循
             int status = 0;
             pid_t rid = waitpid(id, &status, WNOHANG);//-1等待任一个子进程(也可以指定pid), NULL是退出信息, 0是阻塞等待, 一直等
             if (-1 == rid)//等待失败; pid错误/不存在...
             {
                printf("wait fail\n");
                return 0;
             }
             else if (rid > 0)
             {
                 sleep(2);
                 printf("wait success, child pid:%d\n", rid);
                 if (WIFEXITED(status))//status为正常结束的状态时, 返回真
                 {    
                     printf("Child exit_code:%d\n", WEXITSTATUS(status));
                 }
                 else //非正常结束--异常
                 {
                     printf("child exit_signal:%d\n", status & 0x7f);
                 }
                 return 0;
             }   
             else if (0 == rid)
             {
                //成功等待, 但没等到, child可能还没结束
                printf("child running, father check next time\n");  
                //空闲时间, 
                DoOtherThing();
                sleep(1);
             }
         }
    }

    return 0;
}
